import { Component, OnInit, ViewChild } from '@angular/core'
import { take, switchMap } from 'rxjs/operators'
import { NzTreeComponent, NzTreeNode, NzMessageService, NzFormatEmitEvent } from 'ng-zorro-antd'

import { RoleDataService } from '../../role-data.service'
import { DataService } from '@shared/services/data.service'
import { RoleService } from '../../role.service'
import { TreeService } from '@shared/services/tree.service'
import { I18NService } from '@core'
import { EMenuType } from '@shared/enums'

@Component({
  selector: 'app-role-detail-open-function',
  templateUrl: './open-function.component.html',
  styleUrls: ['./open-function.component.less'],
})
export class RoleDetailOpenFunctionComponent implements OnInit {
  constructor(
    private dataService: DataService,
    private roleDataService: RoleDataService,
    private roleService: RoleService,
    private msgSrv: NzMessageService,
    private treeService: TreeService,
    private i18n: I18NService,
  ) {}

  @ViewChild('tree') tree: NzTreeComponent

  isLoading = false
  isExpandAll = false
  nodes: NzTreeNode[]

  defaultCheckedKeys: string[]

  ngOnInit() {
    this.isLoading = true
    const role = this.dataService.role$.value
    let { menus } = role
    if (!menus) {
      menus = []
    }
    this.roleDataService.menuTree$.pipe(take(1)).subscribe(tree => {
      this.nodes = tree
      // 将返回的菜单中的 ordinal 推入 defaultCheckedKeys 中
      this.defaultCheckedKeys = menus.map(m => `${m.ordinal}`)
      this.isLoading = false
    })
  }

  save() {
    const fun: Map<number, number> = new Map()

    const nodes = this.tree.getCheckedNodeList()
    const result = this.treeService.dfs(nodes)
    for (const f of result) {
      fun.set(f, f)
    }
    const menus = Array.from(fun.keys()).sort((a, b) => a - b)
    const role = this.dataService.role$.value
    const { roleId } = role
    this.roleService
      .updateMenusOfRole(roleId, menus)
      .pipe(
        take(1),
        switchMap(() => this.roleService.getRoleById(roleId)),
      )
      .subscribe(newRole => {
        this.msgSrv.success(this.trans('GENERAL.NOTIFICATION.UPDATE_SUCCESS'))
        this.dataService.setRole(newRole)
      })
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }

  onCheckBoxChange(e: NzFormatEmitEvent) {
    const node = e.node

    if (node.level === 0) {
      return
    }

    const menuType = node.origin.origin.menuStatus
    // 如果是不勾选，需要确定当前不勾选的项是不是 menuStatus 为 6的菜单
    if (node.isChecked === false) {
      if (menuType === EMenuType.Mapping) {
        this.unCheckMappingMenu(node)
        return
      }

      return
    }

    let parentNode: NzTreeNode | null
    if (menuType === EMenuType.Menu || menuType === EMenuType.CommonMenu) {
      parentNode = node.getParentNode()
    }
    if (menuType === EMenuType.Mapping) {
      parentNode = node.getParentNode().getParentNode()
    }

    this.setCheckedValueOfMappingMenu(parentNode, true)
  }

  unCheckMappingMenu(node: NzTreeNode) {
    const parent = node.getParentNode()
    if (!parent.isHalfChecked) {
      return
    }

    const siblings = parent.getChildren()
    for (const s of siblings) {
      const menuType = s.origin.origin.menuStatus
      if (menuType !== EMenuType.Menu && menuType !== EMenuType.CommonMenu) {
        continue
      }

      this.setCheckedValueOfMappingMenu(s, false)
    }
  }

  // 将菜单下面的是否展示xxx菜单的checked值设置成给定的值
  setCheckedValueOfMappingMenu(node: NzTreeNode, value: boolean = false) {
    if (!node) {
      return
    }

    const children = node.getChildren()
    for (const s of children) {
      if (s.origin.origin.menuStatus === EMenuType.Mapping) {
        s.isChecked = value
        return
      }
    }
  }
}
